using FytSoa.Application.App.Dto;
using FytSoa.Application.App.Param;
using FytSoa.Application.Cm;
using FytSoa.Application.Cm.Param;
using FytSoa.Application.Sys;
using FytSoa.Common.Extensions;
using FytSoa.Common.Utils;
using FytSoa.Domain.Cm;
using FytSoa.Domain.Core.Param;
using FytSoa.Domain.Core.Result;
using FytSoa.Domain.Sys;
using FytSoa.Sugar;
using Mapster;
using Masuit.Tools.Media;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

namespace FytSoa.Application.App.AppCommunityService;
[ApiExplorerSettings(GroupName = "v5"),AllowAnonymous]
public class AppCommunityService: IApplicationService
{
    private readonly CmCommunityService _communityService;
    private readonly CmCommentService _commentService;
    private readonly CmPraiseShareService _praiseShareService;
    private readonly CmMedalUserService _medalUserService;
    private readonly SysFileService _fileService;
    private readonly SugarRepository<SysAdvInfo> _advRepository;
    private readonly SugarRepository<CmPraiseShare> _praiseShareRepository;
    private readonly SugarRepository<CmCommunity> _communityRepository;
    private readonly SugarRepository<CmMedalUser> _medalUserRepository;
    private readonly IWebHostEnvironment _webHostEnvironment;
    public AppCommunityService(IWebHostEnvironment webHostEnvironment
    ,CmCommunityService communityService
    ,CmCommentService commentService
    ,CmMedalUserService medalUserService
    ,SysFileService fileService
    ,SugarRepository<SysAdvInfo> advRepository
    ,SugarRepository<CmPraiseShare> praiseShareRepository
    ,SugarRepository<CmCommunity> communityRepository
    ,SugarRepository<CmMedalUser> medalUserRepository
    ,CmPraiseShareService praiseShareService)
    {
        _webHostEnvironment = webHostEnvironment;
        _communityService = communityService;
        _commentService = commentService;
        _advRepository = advRepository;
        _fileService = fileService;
        _praiseShareRepository = praiseShareRepository;
        _communityRepository = communityRepository;
        _medalUserRepository = medalUserRepository;
        _praiseShareService = praiseShareService;
        _medalUserService = medalUserService;
    }
    
    /// <summary>
    /// 查询社区推荐广告位
    /// </summary>
    /// <returns></returns>
    public async Task<List<SysAdvInfo>> GetAdvAsync()
    {
        return await _advRepository.AsQueryable()
            .Where(m=>m.Status && m.ColumnId==1579045488185970688)
            .OrderByDescending(m=>m.Id)
            .ToListAsync();
    }

    /// <summary>
    /// 查询点赞列表以及总数
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<PageResult<CmPraiseShareDto>> GetPraiseList(PageParam param)
    {
        param.Limit = 6;
        return await _praiseShareService.GetPagesAsync(param);
    }

    /// <summary>
    /// 查询社区列表内容
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<PageResult<AppCmCommunityDto>> GetCommunityList(CommunityWhereParam param)
    {
        var list = await _communityService.GetPagesAsync(param);
        var result=list.Adapt<PageResult<AppCmCommunityDto>>();
        var idArr = result.Items.Select(m => m.Id).ToList();
        var praiseList = await _praiseShareRepository.GetListAsync(m => idArr.Contains(m.CommunityId) && m.UserId==param.UserId);
        foreach (var item in result.Items)
        {
            item.IsPraise = praiseList.Any(m => m.CommunityId == item.Id);
        }
        return result;
    }
    
    /// <summary>
    /// 根据用户查询领取的勋章
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<PageResult<CmMedalUserDto>> GetMedalUserList(PageParam param)
    {
        return await _medalUserService.GetPagesAsync(param);
    }
    
    /// <summary>
    /// 查询社区内容
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<CmCommunityDto> GetCommunity(long id)
    {
        return await _communityService.GetAsync(id);
    }
    
    /// <summary>
    /// 查询用户查询是否有未领取的勋章
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<CmMedalUser> GetMedalByUser(long id)
    {
        return await _medalUserRepository.AsQueryable()
            .Where(m => m.UserId == id && !m.IsNeck)
            .Includes(m => m.Medal)
            .FirstAsync();
    }
    
    /// <summary>
    /// 查询用户查询是否有未领取的勋章
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<bool> AddMedalNeckAsync(AppMedalNeckParam param)
    {
        return await _medalUserRepository.UpdateAsync(m=>new CmMedalUser()
        {
            IsNeck = true
        },m=>m.Id==param.MedalId);
    }

    /// <summary>
    /// 添加社区内容
    /// </summary>
    /// <param name="model"></param>
    public async Task AddCommunity(CmCommunityAddDto model)
    {
        await _communityService.AddAsync(model);
    }
    
    /// <summary>
    /// 添加赞
    /// </summary>
    /// <param name="param"></param>
    public async Task AddPraiseAsync(CommunityPraiseParam param)
    {
        var isAny =
            await _praiseShareRepository.IsAnyAsync(m => m.CommunityId == param.Id && m.UserId == param.UserId && m.Type==1);
        if (isAny)
        {
            throw new BusinessException("您已经赞过了~");
        }
        await _praiseShareRepository.InsertAsync(new CmPraiseShare()
        {
            Type = 1,
            CommunityId = param.Id,
            UserId = param.UserId
        });
        await _communityRepository.UpdateAsync(m => new CmCommunity()
        {
            Praise = m.Praise + 1
        },m=>m.Id==param.Id);
    }
    
    /// <summary>
    /// 查询社区评论列表内容
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<PageResult<CmCommentDto>> GetCommentList(PageParam param)
    {
        return await _commentService.GetPagesAsync(param);
    }
    
    /// <summary>
    /// 添加社区评论
    /// </summary>
    /// <param name="model"></param>
    public async Task AddComment(CmCommentAddParam model)
    {
        model.Audit = true;
        await _commentService.AddAsync(model);
    }
    
    /// <summary>
    /// 添加社区评论
    /// </summary>
    /// <param name="model"></param>
    public async Task AddCommentReply(CommentReplyParam model)
    {
        await _commentService.AddReplyAsync(model);
    }

    /// <summary>
    /// 上传文件
    /// </summary>
    /// <returns></returns>
    [NoJsonResult]
    [DisableRequestSizeLimit]
    public async Task<dynamic> Upload([FromForm]IFormFile file)
    {
        var path = "/upload/community/" + DateTime.Now.ToShortDateString().Replace("/", "") + "/";
        var res=await _fileService.Upload(file,path);
        var fileExt = FileUtils.GetFileExt(res.path);
        var cover = string.Empty;
        var basePath = _webHostEnvironment.ContentRootPath;
        if (fileExt.ToLower()=="mp4")
        {
            cover = res.path.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)[0] + "_cover.jpg";
            //await FFmpegUtils.SnapshotImage(basePath + res.path, basePath+cover, new TimeSpan(0, 0, 2));
            FFmpegUtils.GenerateThumbnail(basePath + res.path, basePath+cover,basePath+"/upload/ffmpeg");
        }
        else
        {
            var npath = res.path.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)[0] + "_compress.jpg";
            using (var image = await Image.LoadAsync(basePath+res.path))
            {
                var newSize = ResizeImage(image, 600, 1200);
                var aSize = newSize.Split(',');
                image.Mutate(h => h.Resize(Convert.ToInt32(aSize[1]), Convert.ToInt32(aSize[0])));
                await image.SaveAsync(basePath+npath);
            } 
            FileUtils.DeleteFile(basePath+res.path);
            res.path = npath;
        }
        return new
        {
            code=100,
            msg="成功",
            url=AppUtils.Configuration["Service"]+res.path,
            cover=AppUtils.Configuration["Service"]+cover
        };
    }
    
    public string ResizeImage(Image img, int maxWidth, int maxHeight)
    {
        if (img.Width > maxWidth || img.Height > maxHeight)
        {
            double widthRatio = (double)img.Width / (double)maxWidth;
            double heightRatio = (double)img.Height / (double)maxHeight;
            double ratio = Math.Max(widthRatio, heightRatio);
            int newWidth = (int)(img.Width / ratio);
            int newHeight = (int)(img.Height / ratio);
            return newHeight.ToString() + "," + newWidth.ToString();
        }
        else
        {
            return img.Height.ToString() + "," + img.Width.ToString();
        }
    }
}